package com.zl.tby.core.base.util;

import java.io.*;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.util.Map;

/**
 * @author changpeng
 * @since 2025/10/20 16:16
 */
public class HttpConnectionUtils {
    // 超时时间（毫秒）
    private static final int TIMEOUT = 5000;

    /**
     * 发送GET请求
     * @param url 请求URL
     * @param params 请求参数（键值对）
     * @param headers 请求头（可选）
     * @return 响应结果（字符串）
     * @throws IOException 网络异常
     */
    public static String doGet(String url, Map<String, String> params, Map<String, String> headers) throws IOException {
        // 拼接参数到URL
        if (params != null && !params.isEmpty()) {
            url += (url.contains("?") ? "&" : "?") + buildParams(params);
        }

        HttpURLConnection connection = null;
        BufferedReader reader = null;
        try {
            URL requestUrl = new URL(url);
            connection = (HttpURLConnection) requestUrl.openConnection();

            // 设置请求方法
            connection.setRequestMethod("GET");
            // 设置超时
            connection.setConnectTimeout(TIMEOUT);
            connection.setReadTimeout(TIMEOUT);
            // 设置请求头
            setHeaders(connection, headers);

            // 发起请求
            connection.connect();

            // 读取响应
            int responseCode = connection.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK) {
                reader = new BufferedReader(new InputStreamReader(
                        connection.getInputStream(), StandardCharsets.UTF_8));
                StringBuilder response = new StringBuilder();
                String line;
                while ((line = reader.readLine()) != null) {
                    response.append(line);
                }
                return response.toString();
            } else {
                throw new IOException("GET请求失败，响应码：" + responseCode);
            }
        } finally {
            // 释放资源
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (connection != null) {
                connection.disconnect();
            }
        }
    }

    /**
     * 发送POST请求（支持表单提交或JSON提交）
     * @param url 请求URL
     * @param data 请求体数据（表单参数用Map，JSON用String）
     * @param headers 请求头（可选，如Content-Type）
     * @return 响应结果（字符串）
     * @throws IOException 网络异常
     */
    public static String doPost(String url, Object data, Map<String, String> headers) throws IOException {
        HttpURLConnection connection = null;
        BufferedReader reader = null;
        OutputStream out = null;
        try {
            URL requestUrl = new URL(url);
            connection = (HttpURLConnection) requestUrl.openConnection();

            // 设置请求方法
            connection.setRequestMethod("POST");
            // 允许输出（POST需要写请求体）
            connection.setDoOutput(true);
            // 设置超时
            connection.setConnectTimeout(TIMEOUT);
            connection.setReadTimeout(TIMEOUT);
            // 设置请求头
            setHeaders(connection, headers);

            // 处理请求体
            if (data != null) {
                String content;
                if (data instanceof Map) {
                    // 表单提交（默认application/x-www-form-urlencoded）
                    content = buildParams((Map<String, String>) data);
                    if (headers == null || !headers.containsKey("Content-Type")) {
                        connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
                    }
                } else if (data instanceof String) {
                    // JSON提交（需手动设置Content-Type: application/json）
                    content = (String) data;
                } else {
                    throw new IllegalArgumentException("不支持的数据类型：" + data.getClass());
                }

                // 写入请求体
                out = connection.getOutputStream();
                out.write(content.getBytes(StandardCharsets.UTF_8));
                out.flush();
            }

            // 发起请求
            connection.connect();

            // 读取响应
            int responseCode = connection.getResponseCode();
            InputStream inputStream = (responseCode == HttpURLConnection.HTTP_OK)
                    ? connection.getInputStream()
                    : connection.getErrorStream();

            reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
            StringBuilder response = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                response.append(line);
            }

            if (responseCode != HttpURLConnection.HTTP_OK) {
                throw new IOException("POST请求失败，响应码：" + responseCode + "，响应内容：" + response);
            }
            return response.toString();
        } finally {
            // 释放资源
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (connection != null) {
                connection.disconnect();
            }
        }
    }

    /**
     * 构建表单参数（key1=value1&key2=value2）
     */
    private static String buildParams(Map<String, String> params) throws UnsupportedEncodingException {
        StringBuilder sb = new StringBuilder();
        for (Map.Entry<String, String> entry : params.entrySet()) {
            if (sb.length() > 0) {
                sb.append("&");
            }
            // URL编码（防止特殊字符乱码）
            sb.append(URLEncoder.encode(entry.getKey(), StandardCharsets.UTF_8.name()))
                    .append("=")
                    .append(URLEncoder.encode(entry.getValue(), StandardCharsets.UTF_8.name()));
        }
        return sb.toString();
    }

    /**
     * 设置请求头
     */
    private static void setHeaders(HttpURLConnection connection, Map<String, String> headers) {
        if (headers != null && !headers.isEmpty()) {
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                connection.setRequestProperty(entry.getKey(), entry.getValue());
            }
        }
    }
}
